﻿using System.Collections.Concurrent;

namespace DoNet.Common.Cache
{
    /// <summary>
    /// 本地缓存
    /// </summary>
    /// <typeparam name="TKey"></typeparam>
    /// <typeparam name="TValue"></typeparam>
    public class ListCacheManager<TKey, TValue> where TKey : notnull
    {
        /// <summary>
        /// 缓存列表
        /// </summary>
        private readonly ConcurrentDictionary<TKey, List<TValue>> _cache = new ConcurrentDictionary<TKey, List<TValue>>();

        /// <summary>
        /// 添加或更新整个列表
        /// </summary>
        /// <param name="key"></param>
        /// <param name="newList"></param>
        public void AddOrUpdateList(TKey key, List<TValue> newList)
        {
            _cache.AddOrUpdate(key, k => newList, (k, oldList) => newList);
        }

        /// <summary>
        /// 向指定key的列表追加元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void AppendToList(TKey key, TValue value)
        {
            _cache.AddOrUpdate(key, k => new List<TValue> { value }, (k, list) =>
            {
                //var newList = new List<TValue>(oldList);
                list.Add(value);
                return list;
            });
        }

        /// <summary>
        /// 获取列表副本（避免外部修改影响缓存）
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public List<TValue> GetListCopy(TKey key)
        {
            if (_cache.TryGetValue(key, out var list))
            {
                if (list != null)
                {
                    return list;
                }
            }
            return new List<TValue>();
        }

        /// <summary>
        /// 移除整个列表
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool RemoveList(TKey key)
        {
            return _cache.TryRemove(key, out _);
        }

        /// <summary>
        /// 清空所有缓存
        /// </summary>
        public void ClearAll()
        {
            _cache.Clear();
        }
    }
}
